//
//  ClassOptional.swift
//  Swift3.0_Study
//
//  Created by chengfeng on 2016/9/29.
//  Copyright © 2016年 zhaochengfeng. All rights reserved.
//

import Cocoa

class ClassOptional: NSObject {
    func start() -> Void {
        //-----------------------------可选连接----------------------
        //在或者其他的类型,声明的属性或者变量/常量都不可以为空,为了解决这样的问题,swift 就有了可选类型
        //可选连链接就是为了使用可选类型,可选链接可以判断请求或者调用的目标(属性,方法,下标脚本等)是否为空 ,如果目标有值,就调用,否则,分返回nil
        //swift的可选链接与OC的消息为空类似,但是swift 可以使用在任意的类型中,并且失败与否可以被检测到
        
        
        //1,可选链接的实现方式
        /**
         *  属性名?  //属性的可选链接
         下标脚本? //下标脚本的可选链接
         
         方法名? //方法的可选链接
         
         
         
         对象的可选链接的调用方式
         对象.可选连接
         
         */
        
        //2定义属性的可选链接
        
        class Residence {
            class var numberOfRooms: Int? {
                return 100
            }
            var number: Int?
        }
        
        let reClass = Residence()
        
        if let a = Residence.numberOfRooms {
            print("目标值 \(a)")
        }
        else {
            print("目标值为空")
        }
        
        if let num = reClass.number {
            print("目标值 \(num)")
        }
        else {
            print("目标值为空")
        }
        
        //3通过可选链接调用属性,下标脚本和方法
        
        //   1>通过可选链接调用属性的语法形式
        //    可选链接.属性名
        
        
        class  Person {
            var residence: ResidenceA?//nil
        }
        class ResidenceA {
            var numberOfRooms = 10
            subscript(i: Int) -> Int {
                return i
            }
            func printRoomNumber() {
                print("the number of room is \(numberOfRooms)")
            }
        }
        
        let tom = Person()
        if let roomCount = tom.residence?.numberOfRooms {//通过可选链接调用属性
            print("tom的房子有\(roomCount)个房间")
            
        } else {
            print("无法检索房间数")
        }
        
        let john = Person()
        let johnResidence = ResidenceA()
        john.residence = johnResidence //赋值
        if let roomCount = john.residence?.numberOfRooms {//通过可选链接调用属性
            print("jhon的房子有\(roomCount)个房间")
            
        } else {
            print("无法检索房间数")
        }
        
        //通过可选链接调用下标脚本
        
        let Lily = Person()
        
        if let firstRoomName = Lily.residence?[5]{
            print("Lily的房子有\(firstRoomName)个房间")
            
        } else {
            print("无法检索房间数")
        }
        
        if let firstRoomName = john.residence?[5]{
            print("john的房子有\(firstRoomName)个房间")
            
        } else {
            print("无法检索房间数")
        }
        
        //通过可选链接调用方法
        
        let LinMeimei = Person()//
        
        if let _: ()=LinMeimei.residence?.printRoomNumber() {
            print("打印房间数")
        } else {
            
            print("无法打印房间数")
        }
        
        //有值
        if let _: ()=john.residence?.printRoomNumber() {
            print("打印房间数")
        } else {
            
            print("无法打印房间数")
        }
        
        //链接多个链接(链条)
        
        class  PersonB {
            var residence: ResidenceB?//nil
        }
        class ResidenceB {
            var address: Address?
        }
        class Address {
            var street: String?
        }
        
        let Libai=PersonB()
        let LibaiHouse = ResidenceB()
        Libai.residence = LibaiHouse
        
        let libAddress=Address()
        //赋值
        LibaiHouse.address = libAddress
        libAddress.street = "china street"
        
        if let libStreet = Libai.residence?.address?.street { //可选链条
            print("libai的地址为\(libStreet)")
        } else {
            print("无法检索住址")
        }
    }
}
